package com.delu.controller;


import com.alibaba.fastjson.JSONObject;
import com.delu.data.Result;
import com.delu.dto.CommentDTO;
import com.delu.dto.InsuranceDTO;
import com.delu.dto.SiteCarDTO;
import com.delu.dto.UserDTO;
import com.delu.em.ResultEnum;
import com.delu.entity.*;
import com.delu.feign.CouponFeign;
import com.delu.feign.UserFeign;
import com.delu.mapper.*;
import com.delu.utils.JwtUtil;
import com.delu.vo.CommentVO;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 6子的爹
 * @since 2021-12-18
 */
@RestController
@RequestMapping("/site-car")
@Api(value = "订单模块")
public class SiteCarController {

    @Autowired
    private SiteCarMapper siteCarMapper;
    @Autowired
    private InsuranceMapper insuranceMapper;
    @Autowired
    private SiteMapper siteMapper;
    @Autowired
    private UserFeign userFeign;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private TravelOrderMapper travelOrderMapper;

    @Autowired
    private LabelMapper labelMapper;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private CouponFeign couponFeign;

    @Autowired
    private TenantMapper tenantMapper;

    @Autowired
    private MongoTemplate mongoTemplate;

    @GetMapping("getCar")
    @ApiOperation(value = "根据指定的汽车id查询汽车信息")
    @ApiImplicitParam(name="id",value = "汽车id",required = true,paramType = "query")
    public Result getCar(@RequestParam("carId") Long carId, HttpServletRequest request) throws InvocationTargetException, IllegalAccessException {

        String authToken = request.getHeader("authToken");

        Claims userToken = jwtUtil.parseJwt(authToken);

        String id = userToken.getId();

        String numKey = id + "num";

        String timeKey = id + "time";

        SiteCar siteCar = siteCarMapper.selectById(carId);

        SiteCarDTO siteCarDTO = new SiteCarDTO();

        BeanUtils.copyProperties(siteCar, siteCarDTO);

        if (redisTemplate.hasKey(numKey)) {

            String label = siteCar.getLabel();

            String[] labels = label.split(",");

            Set<ZSetOperations.TypedTuple> set = redisTemplate.boundZSetOps(numKey).reverseRangeWithScores(0, 2);

            Arrays.stream(labels).forEach(l -> {

                set.stream().forEach(a -> {

                    if (a.getValue().equals(l)) {

                        redisTemplate.boundZSetOps(numKey).incrementScore(a.getValue(), 1);

                        redisTemplate.boundZSetOps(timeKey).add(a.getValue(), new Date().getTime());

                    }else {

                        redisTemplate.boundZSetOps(numKey).add(l, 1);

                        redisTemplate.boundZSetOps(timeKey).add(l, new Date().getTime());
                    }
                });
            });
        }

        return Result.response(ResultEnum.SUCCESS).setData(siteCarDTO);
    }

    @GetMapping("getIinsurance")
    @ApiOperation(value = "查询所有的保险信息")
    public Result getCar() {

        List<Insurance> insurances = insuranceMapper.selectList(null);

        String s = JSONObject.toJSONString(insurances);

        Result<String> login = userFeign.login("12345", "123");

        List<InsuranceDTO> insuranceDTOS = JSONObject.parseArray(s, InsuranceDTO.class);

        return Result.response(ResultEnum.SUCCESS).setData(insuranceDTOS);
    }

    @GetMapping("getSite")
    @ApiOperation(value = "根据指定的站点id查询站点信息")
    @ApiImplicitParam(name = "siteId", value = "站点id", required = true, paramType = "query")
    public Result getSite(Long siteId) {

        return Result.response(ResultEnum.SUCCESS).setData(siteMapper.selectById(siteId));
    }
    @GetMapping("getTenant")
    @ApiOperation(value = "根据指定的用户id查询,本用户的承租人")
    @ApiImplicitParam(name = "userId", value = "用户id", required = true, paramType = "query")
    public Result getTenant(@RequestParam("userId") Integer userId) {

        Map<String, Object> map = new HashMap<>();

        map.put("user_id", userId);

        List<Tenant> tenants = tenantMapper.selectByMap(map);

        return Result.response(ResultEnum.SUCCESS).setData(tenants);
    }

    //取还车
    @GetMapping("/{orderId}/{returnCarSiteId}")
    public Result getReturnCarInfo(@PathVariable("orderId") String orderId, @PathVariable("returnCarSiteId") String returnCarSiteId) {

        long l = Long.parseLong(orderId);

        TravelOrder travelOrder = travelOrderMapper.selectById(l);

        SiteCar siteCar = siteCarMapper.selectById(travelOrder.getCarId());

        LocalDate endTime = travelOrder.getEndTime();

        LocalDateTime localDateTime = endTime.atStartOfDay();

        long epochSecond = localDateTime.toInstant(ZoneOffset.ofHours(8)).getEpochSecond();

        Long realmTime = epochSecond + (30L * 60 * 1000);

        if (new Date().getTime() > realmTime) {

            Long outTime = new Date().getTime() - realmTime.longValue();

            return Result.response(ResultEnum.SUCCESS).setData(outTime.toString());
        }

        if (!returnCarSiteId.equals(siteCar.getSiteId().toString())) {

            siteCar.setAbleFreeRide(1);

            siteCarMapper.updateById(siteCar);
        }

        rocketMQTemplate.convertAndSend("returSuccess", travelOrder.getUserId().toString());

        return Result.response(ResultEnum.SUCCESS);
    }

    @GetMapping("/{orderId}")
    public Result pickCar(@PathVariable("orderId") String orderId) {

        TravelOrder travelOrder = travelOrderMapper.selectById(Long.parseLong(orderId));

        SiteCar siteCar = siteCarMapper.selectById(travelOrder.getCarId());

        siteCar.setRentAble(0);

        siteCar.setBookAble(0);

        siteCarMapper.updateById(siteCar);

        LocalDate startTime = travelOrder.getStartTime();

        LocalDateTime localDateTime = startTime.atStartOfDay();

        int startHour = localDateTime.getHour();

        /*long epochSecond = localDateTime.toInstant(ZoneOffset.ofHours(8)).getEpochSecond();*/

        LocalDateTime time = LocalDateTime.now();

        long epochSecond = travelOrder.getEndTime().atStartOfDay().toInstant(ZoneOffset.ofHours(8)).getEpochSecond();

        int hour = time.getHour();

        if (hour - startHour == 2) {

            travelOrder.setOrderStatus(0);

            travelOrderMapper.updateById(travelOrder);

            return Result.response(ResultEnum.SUCCESS);

        }else if (hour - startHour == 8 && siteCar.getLeaseId() == 4) {

            double rentPrice = siteCar.getRentPrice().doubleValue() * 0.3;

            return Result.response(ResultEnum.SUCCESS).setData(rentPrice);

        }else if (siteCar.getAbleFreeRide() == 1 && new Date().getTime() == epochSecond) {

            travelOrder.setOrderStatus(0);

            travelOrderMapper.updateById(travelOrder);

            double rentPrice = siteCar.getAbleFreePrice().doubleValue() * 0.3;

            return Result.response(ResultEnum.SUCCESS).setData(rentPrice);
        }

        rocketMQTemplate.convertAndSend("getSuccess", travelOrder.getUserId().toString());

        return Result.response(ResultEnum.SUCCESS);
    }

    //查询单个汽车下的所有评论所有
    @GetMapping("getComment")
    @ApiOperation(value = "根据指定汽车id,和用户id所有评论")
    @ApiImplicitParam(name = "carId", value = "汽车id", required = true, paramType = "query")
    public Result getComment(@RequestParam("carId") Integer carId) {

        CommentVO commentVO = new CommentVO();

        List<Comment> commentList = mongoTemplate.find(Query.query(Criteria.where("parentId").ne(carId)), Comment.class);

        List<CommentDTO> commentDTOParentList = JSONObject.parseArray(JSONObject.toJSONString(commentList), CommentDTO.class);

        Map<String,List<CommentDTO>> commentSonMap = new HashMap<>();

        for (Comment comment : commentList) {

            List<Comment> articleUserList = mongoTemplate.find(Query.query(Criteria.where("articleId").ne(comment.getUserId())), Comment.class);

            List<CommentDTO> commentDTOList = JSONObject.parseArray(JSONObject.toJSONString(articleUserList), CommentDTO.class);

            commentSonMap.put(comment.getUserId(),commentDTOList);

        }
        commentVO.setCommentList(commentDTOParentList);
        commentVO.setArticleUserList(commentSonMap);

        return Result.response(ResultEnum.SUCCESS).setData(commentVO);
    }

    @PostMapping("addComment")
    @ApiOperation(value = "根据前台传过来一个Comment实体类进行增加")
    @ApiImplicitParam(name = "Comment", value = "评论实体类", required = true, paramType = "body")
    public Result addComment(@RequestBody CommentDTO commentDTO,HttpServletRequest request){

        String authToken = request.getHeader("authToken");

        Claims claims = jwtUtil.parseJwt(authToken);

        UserDTO userDTO = JSONObject.parseObject(claims.getSubject(), UserDTO.class);

        mongoTemplate.save(commentDTO);

        //修改订单状态
        return Result.response(ResultEnum.SUCCESS);
    }


}
